<?php

namespace App\Service;

use ParagonIE\Halite\Alerts\CannotPerformOperation;
use ParagonIE\Halite\Alerts\InvalidDigestLength;
use ParagonIE\Halite\Alerts\InvalidKey;
use ParagonIE\Halite\Alerts\InvalidMessage;
use ParagonIE\Halite\Alerts\InvalidSalt;
use ParagonIE\Halite\Alerts\InvalidSignature;
use ParagonIE\Halite\Alerts\InvalidType;
use ParagonIE\Halite\Symmetric\Crypto;
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric\EncryptionKey;
use ParagonIE\HiddenString\HiddenString;
use SodiumException;

class Cryptor
{
    private EncryptionKey $encryptionKey;

    /**
     *
     * @throws InvalidType
     * @throws InvalidKey
     * @throws InvalidSalt|SodiumException
     */
    public function __construct()
    {
        $this->encryptionKey = KeyFactory::deriveEncryptionKey(
            new HiddenString('PasswordEnergy20250304',false),
            new HiddenString('SaltEnergy202503',false)
        );
    }

    /**
     *
     * 数据加密
     * @param array $data
     * @return string
     * @throws CannotPerformOperation
     * @throws InvalidDigestLength
     * @throws InvalidMessage
     * @throws InvalidType
     * @throws SodiumException
     */
    public function encryptLicense(array $data): string
    {
        return Crypto::encrypt(new HiddenString(json_encode($data)), $this->encryptionKey);
    }

    /**
     * 数据解密
     * @param string $cipher
     * @return array
     * @throws CannotPerformOperation
     * @throws InvalidDigestLength
     * @throws InvalidMessage
     * @throws InvalidType
     * @throws SodiumException
     * @throws InvalidSignature
     */
    public function decryptLicense(string $cipher): array
    {
        $decrypted = Crypto::decrypt($cipher, $this->encryptionKey);
        return json_decode($decrypted->getString(), true);
    }
}